import "@site/src/languages/highlight";

# Chapter 2: Scenes and Nodes: Building a Game World

In this chapter, we'll dive into **Dora**'s scenes and nodes, build a simple game world, and set up the game window. These concepts will lay the foundation for your future development.

Before we get started, let's prepare a new game project.

* 1. Create a project named `dodge_the_creeps` in Dora's Web IDE, and create a TSX file named `init` in the project folder as the game's entry point.
* 2. Upload the necessary game resources (e.g., images, audio) to the project folder by right-clicking on the `dodge_the_creeps` directory and using the upload option. The resources used in this tutorial can be downloaded [here](https://github.com/IppClub/Dora-Demo/tree/main/dodge_the_creeps).

Once everything is ready, your project structure should look like this:

```plaintext
dodge_the_creeps
├── Audio
│   ├── House In a Forest Loop.ogg
│   └── gameover.wav
├── Font
│   └── Xolonium-Regular.ttf
├── Image
│   ├── art.clip
│   └── art.png
└── init.tsx
```

Now, let's start building the game world step by step and bring the game to life.

:::tip Tip
The sample code in this tutorial will be displayed as `Code Sample` and `dodge_the_creeps/init.tsx`. The former represents explanatory code snippets, while the latter contains full executable code you can copy into your project.
:::

---

## 1. Basic Concepts of Scenes and Nodes

In game development, a “scene” represents a part of the game, such as the main menu, the game scene, or the end scene. Elements within a scene are called “nodes,” which can include sprites, physics objects, labels, and more.

In **Dora**:

- **Scene**: A container for nodes. It represents a specific screen or part of the game, hosting all content displayed on the screen.
- **Node**: The smallest building block of the game. Nodes can be nested and combined.

The scene and node structure is usually tree-like, with all nodes managed by a root node.

---

## 2. Creating a Game Window and Basic Scene

Let's begin by creating a game window and setting up the basic scene. Below is an example of initializing the game window:

```tsx title="dodge_the_creeps/init.tsx"
import { Director, View, Camera2D, Vec2 } from 'Dora';

const width = 480; // Design width of the window
const height = 700; // Design height of the window

const DesignSceneHeight = height;
const updateViewSize = () => {
	const camera = Director.currentCamera as Camera2D.Type;
	camera.zoom = View.size.height / DesignSceneHeight;
};

updateViewSize();
// Listen for window size changes for adaptation
Director.entry.onAppChange(settingName => {
	if (settingName === 'Size') {
		updateViewSize();
	}
});
```

#### Code Explanation:

1. **Importing Modules**: `Director` is the scene manager, while `View` provides game window information.
2. **Setting Window Dimensions**: The width and height of the window are defined, and the `updateViewSize` function adjusts the scene's scale to fit different screen sizes.
3. **Responding to Window Size Changes**: The `Director.entry.onAppChange` listener ensures the window always fits the design dimensions.

---

## 3. Creating a Background Node

After setting up the game window, let's create a simple background node to serve as the stage for adding player characters and enemies.

```tsx title="dodge_the_creeps/init.tsx"
import { React, toNode } from 'DoraX';

const Rect = () => (
	<draw-node>
		<rect-shape width={width} height={height} fillColor={0xff4b6b6c}/>
	</draw-node>
);

toNode(<Rect/>);
```

#### Code Explanation:

1. **`Rect` Component**: A `draw-node` is used to create a drawing node, and `rect-shape` specifies the background rectangle's width, height, and color.
2. **Rendering the Background**: The `toNode(<Rect/>)` function adds the background node to the scene.

> Tip: The `fillColor` property accepts hexadecimal color values. For example, `0xff4b6b6c` represents a gray-green background.

---

## 4. Managing Scenes with `Director`

`Director` is the core module for scene management. It can:

- Load, switch, and delete scenes;
- Add UI nodes like buttons and score displays.

Let's add a start screen for the game to allow players to begin:

```tsx title="dodge_the_creeps/init.tsx"
import { emit } from 'Dora';

const StartUp = () => {
	return (
		<>
			<Rect/>
			<label fontName='Xolonium-Regular' fontSize={80} text='Dodge the Creeps!' textWidth={400}/>
			<draw-node y={-150}>
				<rect-shape width={250} height={80} fillColor={0xff3a3a3a}/>
				<label fontName='Xolonium-Regular' fontSize={60} text='Start'/>
				<node width={250} height={80} onTapped={() => emit('Input.Start')}/>
			</draw-node>
		</>
	);
};

toNode(<StartUp/>)?.addTo(Director.ui);
```

#### Code Explanation:

1. **Title and Start Button**: A `<label>` displays the game name, while a `<draw-node>` creates a button. The `onTapped` event listens for clicks and triggers the `Input.Start` event.
2. **Starting the Game**: The `emit('Input.Start')` function sends an input signal, which will be used in later chapters to start the game.
3. **Adding to the Scene**: The start screen is added to the UI scene using `addTo(Director.ui)`.

---

## 5. Creating and Adding Nodes with `toNode`

`toNode` is a key utility function that converts JSX elements into game nodes. It allows you to define the game interface and structure using JSX syntax, just like in React. Below is how you add nodes to the scene:

```tsx
toNode(<Rect/>); // Add background
toNode(<StartUp/>); // Add start screen
```

---

## 6. Chapter Summary

In this chapter, you learned how to:

- Set the dimensions and scaling of the game window;
- Create a simple background node;
- Manage game scenes with `Director`;
- Create a start screen and respond to player interactions.

In the next chapter, we'll explore **sprites and animations**, bringing scenes and characters to life.
